#include <iostream>
#include <fstream>
#include <sstream>
#include <cstring>
#include <vector>
#include <string>
#include "zlib.h"

// 压缩数据
bool compressData(const std::string& input, std::string& output) {
    z_stream stream;
    memset(&stream, 0, sizeof(stream));

    if (deflateInit(&stream, Z_BEST_COMPRESSION) != Z_OK) {
        return false;
    }

    stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(input.data()));
    stream.avail_in = static_cast<uInt>(input.size());

    const size_t bufferSize = 128 * 1024;  // 128 KB
    std::vector<Bytef> buffer(bufferSize);
    std::stringstream compressed;

    do {
        stream.next_out = buffer.data();
        stream.avail_out = static_cast<uInt>(buffer.size());

        int result = deflate(&stream, Z_FINISH);
        if (result == Z_STREAM_ERROR) {
            deflateEnd(&stream);
            return false;
        }

        size_t compressedSize = bufferSize - stream.avail_out;
        compressed.write(reinterpret_cast<const char*>(buffer.data()), compressedSize);
    } while (stream.avail_out == 0);

    deflateEnd(&stream);

    output = compressed.str();
    return true;
}

// 解压缩数据
bool decompressData(const std::string& input, std::string& output) {
    z_stream stream;
    memset(&stream, 0, sizeof(stream));

    if (inflateInit(&stream) != Z_OK) {
        return false;
    }

    stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(input.data()));
    stream.avail_in = static_cast<uInt>(input.size());

    const size_t bufferSize = 128 * 1024;  // 128 KB
    std::vector<Bytef> buffer(bufferSize);
    std::stringstream decompressed;

    do {
        stream.next_out = buffer.data();
        stream.avail_out = static_cast<uInt>(buffer.size());

        int result = inflate(&stream, Z_NO_FLUSH);
        if (result == Z_STREAM_ERROR || result == Z_NEED_DICT || result == Z_DATA_ERROR ||
            result == Z_MEM_ERROR) {
            inflateEnd(&stream);
            return false;
        }

        size_t decompressedSize = bufferSize - stream.avail_out;
        decompressed.write(reinterpret_cast<const char*>(buffer.data()), decompressedSize);
    } while (stream.avail_out == 0);

    inflateEnd(&stream);

    output = decompressed.str();
    return true;
}

int main() {
    std::string originalData = "Hello, this is a test string for zlib compression and decompression.";

    // 压缩数据
    std::string compressedData;
    if (compressData(originalData, compressedData)) {
        std::cout << "Compressed data size: " << compressedData.size() << std::endl;

        // 解压缩数据
        std::string decompressedData;
        if (decompressData(compressedData, decompressedData)) {
            std::cout << "Decompressed data: " << decompressedData << std::endl;
        } else {
            std::cerr << "Failed to decompress data." << std::endl;
        }
    } else {
        std::cerr << "Failed to compress data." << std::endl;
    }

    return 0;
}
